package com.scwatch.ext.web.back;

import com.alibaba.fastjson.JSONObject;
import com.scwatch.common.orm.RowSide;
import com.scwatch.common.util.CreateWowza;
import com.scwatch.common.util.Dates;
import com.scwatch.common.web.Servlets;
import com.scwatch.core.constant.Constants;
import com.scwatch.core.domain.*;
import com.scwatch.core.html.HtmlGenerator;
import com.scwatch.core.service.*;
import com.scwatch.core.support.Backends;
import com.scwatch.core.support.Context;
import com.scwatch.ext.domain.LiveBroadcast;
import com.scwatch.ext.domain.LiveBroadcastAddress;
import com.scwatch.ext.service.LiveBroadcastAddressService;
import com.scwatch.ext.service.LiveBroadcastService;
import com.scwatch.ext.wowza.wowzaTools;
import org.apache.commons.codec.binary.Base64;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

import static com.scwatch.core.constant.Constants.*;

/**
 * 直播管理
 */
@Controller
@RequestMapping("/ext/livebroadcast")
public class LiveBroadcastController {
    private static final Logger logger = LoggerFactory
            .getLogger(LiveBroadcastController.class);

    public static final String TYPE = "stat";

    @Autowired
    private UserMemberGroupService userMemberGroupService;

    @Autowired
    private OrgService orgService;

    @Autowired
    private UserMemberGroupService memberGroupService;


    /*----------------------[ 获取对应的分组信息 ]--------------------------*/
    @RequestMapping("groupView.do")
    @ResponseBody
    public String groupView(HttpServletRequest request,
                            Integer orgId) {
        Integer[] types = new Integer[]{4, 5};
        Object obj = userMemberGroupService.getUserGroupType(orgId, types);
        String value = JSONObject.toJSONString(obj);
        return value;
    }

    @RequiresPermissions("ext:livebroadcast:liveSave")
    @RequestMapping("liveSave.do")
    public String liveSave(HttpServletRequest request,
                           Integer broadcastId, String stat, RedirectAttributes ra, String title) {
        Site site = Context.getCurrentSite();
        String serverurl = site.getWoWzaUrl();//服务器地址
        String cearUrl = site.getWoWzaExteriorUrl();//创建
        String appUrl = site.getWoWzaAppUrl();//app推流地址
        String[] ip_port = cearUrl.split(":");

//        wowzaTools tools = new wowzaTools(serverurl, "rtmp://" + cearUrl);
        /*---------------------[ 拼接 地址 输入、输出 ]--------------*/
        String uuidNmae = Base64.encodeBase64String(Dates.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss").getBytes());
        uuidNmae = uuidNmae.replaceAll("==", "");

        String inputStear = "gocoder://configure/?publishHost=%s&publishPort=%s&publishApplication=%s&publishStream=%s&publishUseTCP=YES&publishUser=sctv";
        StringBuffer outStear = new StringBuffer("http://");
        String Application = "live" + broadcastId;//PinyinUtils.converterToFirstSpell(title);//直播间
        String streamfile = uuidNmae;//输出的

        //输入地址
        inputStear = String.format(inputStear, ip_port[0], ip_port[1], Application, Application + streamfile);
        //输出
        outStear.append(appUrl).append("/").append(Application).append("/").append(Application + streamfile).append("/playlist.m3u8");
        try {

            LiveBroadcast bean = service.get(broadcastId);
            if (bean != null) {
                if (!bean.getWowzaType()) {
                    wowzaTools tools = new wowzaTools(serverurl, cearUrl);
                    String ApplicationName = "live" + bean.getId();//PinyinUtils.converterToFirstSpell(bean.getTitle());
                    if (!(tools.hasApplicationInfo(ApplicationName))) {
                /*-------------------[ wowza 没有 创建 ]------------------------*/
                        if (tools.CreateApplication(ApplicationName)) {
                            bean.setWowzaType(true);
                            service.save(bean, site.getId());
                        }
                    }
                }
            }
            LiveBroadcastAddress address = new LiveBroadcastAddress();
            LiveBroadcast b = new LiveBroadcast();
            b.setId(broadcastId);
            address.setLiveBroadcast(b);
            address.setCreateTime(new Date());
            address.setImputAddress(inputStear);
            address.setOutAddress(outStear.toString());
            address.setStreamName(Application + streamfile);
            address = addressService.saveOrUpdata(address);
        } catch (Exception e) {
            e.getLocalizedMessage();
        } finally {
            ra.addAttribute("id", broadcastId);
            ra.addAttribute(TYPE, stat);
            return "redirect:edit.do";
        }
    }


    @RequiresPermissions("ext:livebroadcast:liveEdit")
    @RequestMapping("liveEdit.do")
    public String liveEdit(org.springframework.ui.Model modelMap,
                           @RequestParam(required = true) Integer addressId, String stat) {
        LiveBroadcastAddress bean = addressService.get(addressId);

        /*------------------[ 获取组织]------------------*/
        List<Org> list = orgService.findList();

        modelMap.addAttribute("address", bean);
        modelMap.addAttribute("orgList", list);
        modelMap.addAttribute("stat", stat);
        return "ext/livebroadcast/livebroadcast_address_form";
    }


    @RequiresPermissions("ext:livebroadcast:liveUpata")
    @RequestMapping("liveUpata.do")
    public String liveUpata(HttpServletRequest request, LiveBroadcastAddress bean,
                            RedirectAttributes ra,Integer userId,
                            String stat, String redirect) {
        Integer broadcastId = bean.getLiveBroadcast().getId();
        if(userId!=null){
            bean.setUser(userService.get(userId));
        }
        bean.setCreateTime(new Date());
        addressService.saveOrUpdata(bean);

        ra.addFlashAttribute(MESSAGE, OPERATION_SUCCESS);
        ra.addAttribute(TYPE, stat);
        if (Constants.REDIRECT_EDIT.equals(redirect)) {
            ra.addAttribute("id", broadcastId);
            return "redirect:edit.do";
        } else {
            ra.addAttribute("addressId", bean.getId());
            return "redirect:liveEdit.do";

        }
    }


    @RequiresPermissions("ext:livebroadcast:liveDelete")
    @RequestMapping("liveDelete.do")
    public String liveDelete(Integer[] ids, Integer id, HttpServletRequest request,
                             RedirectAttributes ra) {
        String stat = request.getParameter(TYPE);
        LiveBroadcastAddress[] beans = addressService.delete(ids);

        for (LiveBroadcastAddress bean : beans) {
            try {
            } finally {
                logService.operation("opr.livebroadcast.liveDelete", "输入地址：" + bean.getImputAddress() + " -- 输出地址：" + bean.getOutAddress(), null,
                        bean.getId(), request);
                logger.info("delete LiveBroadcast, title={}.", "输入地址：" + bean.getImputAddress() + " -- 输出地址：" + bean.getOutAddress());
            }
        }
        ra.addFlashAttribute(MESSAGE, DELETE_SUCCESS);
        ra.addAttribute(TYPE, stat);
        ra.addAttribute("id", beans[0].getLiveBroadcast().getId());
        return "redirect:edit.do";
    }


    /**
     * 直播管理，查询直播
     * @param pageable
     * @param request
     * @param modelMap
     * @param id
     * @return 结果页面
     */
    @RequiresPermissions(value = {
            "ext:livebroadcast:list",
            "ext:livebroadcast:subscribe_List",
            "ext:livebroadcast:lookback_List",
    }, logical = Logical.OR)
    @RequestMapping("list.do")
    public String liveList(
            @PageableDefault(sort = "id", direction = Sort.Direction.DESC) Pageable pageable,
            HttpServletRequest request, org.springframework.ui.Model modelMap, Integer id) {
        Integer siteId = Context.getCurrentSiteId();

        String stat = request.getParameter("stat");


        Map<String, String[]> params = Servlets.getParamValuesMap(request,
                Constants.SEARCH_PREFIX);

        if (!params.containsKey("EQ_status")) {
            params.put("EQ_status", new String[]{stat});
        }

        stat = params.get("EQ_status")[0];
        Page<LiveBroadcast> pagedList = service.findAll(siteId, params, pageable);
        modelMap.addAttribute("pagedList0", pagedList);
        modelMap.addAttribute("liveid", id);
        modelMap.addAttribute(TYPE, stat);
        return "ext/livebroadcast/livebroadcast_list";
    }


    @RequiresPermissions("ext:livebroadcast:create")
    @RequestMapping("create.do")
    public String create(Integer id, org.springframework.ui.Model modelMap, HttpServletRequest request) {
        Site site = Context.getCurrentSite();
        String per = request.getParameter("per");

        String stat = request.getParameter("stat");
        modelMap.addAttribute(TYPE, stat);
        String o = "ext/livebroadcast/livebroadcast_form";
        if (id != null) {
            LiveBroadcast bean = service.get(id);
            Backends.validateDataInSite(bean, site.getId());
            modelMap.addAttribute("bean", bean);
        }
        modelMap.addAttribute("site", site);
        modelMap.addAttribute(OPRT, CREATE);
        return o;
    }

    /**
     * 创建直播
     * @param bean 直播数据对象
     * @param itemCount
     * @param redirect
     * @param request
     * @param ra
     * @param subscribe
     * @param review
     * @return 结果页面
     */
    @RequiresPermissions("ext:livebroadcast:save")
    @RequestMapping("save.do")
    public String save(LiveBroadcast bean, Integer[] itemCount,
                       String redirect, HttpServletRequest request, RedirectAttributes ra, Integer subscribe, Integer review) {


        Integer siteId = Context.getCurrentSiteId();
        bean.setUser(Context.getCurrentUser());
        bean.setWowzaType(false);
        bean.setCreatetime(new Date());
        if(bean.getRealviews()==null){
            bean.setRealviews(0);
        }
        if(bean.getViews()==null){
            bean.setViews(0);
        }
        bean = service.save(bean, siteId);
        /*-------------------[ woWza  菜单 创建 ]----------------*/
        Integer id = bean.getId();
        try {

        } catch (Exception e) {
            e.getMessage();
        } finally {
            String stat = request.getParameter("stat");
            logService.operation("opr.LiveBroadcast.add", bean.getTitle(), null,
                    bean.getId(), request);
            logger.info("save LiveBroadcast, title={}.", bean.getTitle());
            ra.addFlashAttribute(MESSAGE, SAVE_SUCCESS);
            ra.addAttribute(TYPE, stat);
            if (Constants.REDIRECT_LIST.equals(redirect)) {
                return "redirect:list.do";
            } else if (Constants.REDIRECT_CREATE.equals(redirect)) {
                return "redirect:create.do";
            } else {
                ra.addAttribute("id", bean.getId());
                return "redirect:edit.do";
            }
        }
    }

    @RequiresPermissions("ext:livebroadcast:edit")
    @RequestMapping("edit.do")
    public String edit(
            @RequestParam(required = true) Integer id,
            Integer position,
            @PageableDefault(sort = "id", direction = Sort.Direction.DESC) Pageable pageable,
            HttpServletRequest request, org.springframework.ui.Model modelMap) {
        Integer siteId = Context.getCurrentSiteId();
        Site site = Context.getCurrentSite();
        LiveBroadcast bean = service.get(id);
        Backends.validateDataInSite(bean, siteId);
        Map<String, String[]> params = Servlets.getParamValuesMap(request,
                Constants.SEARCH_PREFIX);
        RowSide<LiveBroadcast> side = service.findSide(siteId, params, bean, pageable.getSort());

        String stat = request.getParameter("stat");
        modelMap.addAttribute(TYPE, stat);

        modelMap.addAttribute("bean", bean);
        modelMap.addAttribute("site", site);
        modelMap.addAttribute("side", side);
        modelMap.addAttribute("position", position);
        modelMap.addAttribute(OPRT, EDIT);
        return "ext/livebroadcast/livebroadcast_form";
    }

    /**
     * 修改直播
     * @param bean 直播对象
     * @param id 数据id
     * @param title 标题
     * @param status 状态
     * @param subscribe
     * @param review
     * @param ra
     * @param request
     * @param redirect
     * @return 结果页面
     */
    @RequiresPermissions("ext:livebroadcast:update")
    @RequestMapping("update.do")
    public String update(@ModelAttribute("bean") LiveBroadcast bean, Integer[] id,
                         String[] title, Integer status, Integer subscribe,
                         Integer review, RedirectAttributes ra, HttpServletRequest request,
                         String redirect) {
        String stat = request.getParameter("stat");
        Site site = Context.getCurrentSite();
//        bean.setLiveroom(0);
//        bean.setReview(0);
//        bean.setSubscribe(0);
        bean.setSite(site);
        bean.setUser(Context.getCurrentUser());
        validateOptionIds(id, site.getId());

        if(bean.getCreatetime()==null){
          bean.setCreatetime(new Date());
        }
        if(bean.getRealviews()==null){
            bean.setRealviews(0);
        }
        if(bean.getViews()==null){
            bean.setViews(0);
        }
        Backends.validateDataInSite(bean, site.getId());


        service.update(bean, id, title);

        logger.info("update LiveBroadcast, title={}.", bean.getTitle());
        ra.addFlashAttribute(MESSAGE, SAVE_SUCCESS);
        ra.addAttribute(TYPE, stat);
        if (Constants.REDIRECT_LIST.equals(redirect)) {

            return "redirect:list.do";
        } else {
            ra.addAttribute("id", bean.getId());
            return "redirect:edit.do";
        }
    }

    /**
     * 删除直播
     * @param ids
     * @param request
     * @param stat 状态
     * @param ra
     * @return
     */
    @RequiresPermissions("ext:livebroadcast:delete")
    @RequestMapping("delete.do")
    public String delete(Integer[] ids, HttpServletRequest request, String stat,
                         RedirectAttributes ra) {
        Site site = Context.getCurrentSite();
        validateIds(ids, site.getId());
        LiveBroadcast[] beans = new LiveBroadcast[0];
        try {
            List<Integer> liveIds = Arrays.asList(ids);
            List<Info> infos=infoQueryService.findInfoByLiveAndSite(liveIds,site.getId());
            if(infos!=null && infos.size()>0){
                ra.addFlashAttribute(MESSAGE, LIVE_REF);
                ra.addAttribute(TYPE, stat);
                return "redirect:list.do";
            }
            beans = service.delete(ids);
        }catch (Exception e){
            ra.addFlashAttribute(MESSAGE, OPERATION_FAILURE);
            ra.addAttribute(TYPE, stat);
            return "redirect:list.do";
//            e.printStackTrace();
        }
        //清理静态json
        Node rootnode=nodeQueryService.findRoot(site.getId());
        for(LiveBroadcast broadcast:beans){
            htmlGenerator.deleteLiveJson(site,broadcast,rootnode);
        }
        String serverurl = site.getWoWzaUrl();//服务器地址
        String cearUrl = site.getWoWzaExteriorUrl();//创建
        cearUrl = "rtmp://" + cearUrl;
        wowzaTools tools = new wowzaTools(serverurl, cearUrl);
        try {

            for (LiveBroadcast bean : beans) {
            /*----------------------------[ 删除对应的 直播地址 ]------------------------------*/
                try {
                    if (bean.getWowzaType()) {
                        String ApplicationName = "live" + bean.getId();//PinyinUtils.converterToFirstSpell(bean.getTitle());
                        try {
                            if ((tools.hasApplicationInfo(ApplicationName))) {
                    /*-------------------[ wowza 没有 创建 应用 ]------------------------*/
                                tools.DeleteApplicationName(ApplicationName);
                            }
                        } catch (Exception e) {
                            System.out.println("----------------【删除直播】 异常: 名称[ " + ApplicationName + " ]");
                        }
                    }
                } finally {
                    logService.operation("opr.livebroadcast.delete", bean.getTitle(), null,
                            bean.getId(), request);
                    logger.info("delete LiveBroadcast, title={}.", bean.getTitle());
                }
            }
            ra.addFlashAttribute(MESSAGE, DELETE_SUCCESS);
        } catch (Exception e) {
            e.getMessage();
            ra.addFlashAttribute(MESSAGE, OPERATION_FAILURE);
        }
        ra.addAttribute(TYPE, stat);
        return "redirect:list.do";
    }


    /**
     * 创建wowza
     * @param request
     * @return
     */
    @RequestMapping("wowza.do")
    @ResponseBody
    public Map wowza(HttpServletRequest request) {
        String stream = "rrr";
        String targetURL2 = "http://192.168.32.201:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/live/streamfiles";
        String input2 = "{" +
                "   \"name\": \"" + stream + "\"," +
                "   \"serverName\": \"_defaultServer_\"," +
                "   \"uri\": \"rtmp://192.168.32.201:1935\"" +
                "}";
        String application = "uuu";
        String targetURL1 = "http://192.168.32.201:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/" + application;
        String input1 = "{" +
                "restURI\": \"http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive333\"," +
                "name\": \"testlive333\"," +
                "appType\": \"Live\"," +
                "clientStreamReadAccess\": \"*\"," +
                "clientStreamWriteAccess\": \"*\"," +
                "description\": \"A basic live application\"," +
                "streamConfig\": {" +
                "restURI\": \"http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/testlive333/streamconfiguration\"," +
                "streamType\": \"live\"" +
                "}";
        //创建application
        CreateWowza.Create(targetURL1, input1);
        //创建stream
        CreateWowza.Create(targetURL2, input2);

        String createapplication = "http://192.168.32.201:1935/" + application + "/" + stream + ".stream";
        String createstream = "http://192.168.32.201:1935/" + application + "/" + stream + ".stream/playlist.m3u8";

        Map result = new HashMap();
        result.put("createstream", createstream);
        result.put("createapplication", createapplication);

        return result;
    }

    /**
     * 直播管理：生成直播
     * @param ra
     * @param liveId 直播id
     * @param request
     * @param modelMap
     * @return 结果页面
     */
    @RequestMapping("generationLiveManage.do")
    @RequiresRoles("super")
    @RequiresPermissions("ext:livebroadcast:genLives")
    public String generationLiveManage(RedirectAttributes ra,Integer liveId,
                                 HttpServletRequest request,org.springframework.ui.Model modelMap) {
        String stat = request.getParameter("stat");
//        String page = request.getParameter("page");
        Site site=Context.getCurrentSite();
        User user=Context.getCurrentUser();
        LiveBroadcast live=service.get(liveId);
        Node rootnode=nodeQueryService.findRoot(site.getId());
        htmlGenerator.generationLiveManage(site,live,rootnode);
        String ip = Servlets.getRemoteAddr(request);
        logService.operation("opr.generationLiveManage","生成直播管理直播", null,liveId,ip,user.getId(), site.getId());
        logger.info("generationLiveManage json");
        ra.addFlashAttribute(MESSAGE, SAVE_SUCCESS);
        ra.addAttribute(TYPE, stat);
//        ra.addAttribute("page",page);
        return "redirect:list.do";
    }

    /**
     * 直播管理：清理json数据
     * @param ra
     * @param liveId 直播id
     * @param request
     * @param modelMap
     * @return 结果页面
     */
    @RequestMapping("delLiveJson.do")
    @RequiresRoles("super")
    @RequiresPermissions("ext:livebroadcast:delLiveJson")
    public String delLiveJson(RedirectAttributes ra,Integer liveId,
                                       HttpServletRequest request,org.springframework.ui.Model modelMap) {
        String stat = request.getParameter("stat");
        Site site=Context.getCurrentSite();
        User user=Context.getCurrentUser();
        LiveBroadcast live=service.get(liveId);

        //判断直播是否有引用
        try {
            List<Integer> liveIds = Arrays.asList(liveId);
            List<Info> infos=infoQueryService.findInfoByLiveAndSite(liveIds,site.getId());
            if(infos!=null && infos.size()>0){
                ra.addFlashAttribute(MESSAGE, LIVE_REF);
                ra.addAttribute(TYPE, stat);
                return "redirect:list.do";
            }
        }catch (Exception e){
            ra.addFlashAttribute(MESSAGE, OPERATION_FAILURE);
            ra.addAttribute(TYPE, stat);
            return "redirect:list.do";
        }

        Node rootnode=nodeQueryService.findRoot(site.getId());
        htmlGenerator.deleteLiveJson(site,live,rootnode);
        String ip = Servlets.getRemoteAddr(request);
        logService.operation("opr.delLiveJson","直播管理，清理直播json", null,liveId,ip,user.getId(), site.getId());
        logger.info("delLiveJson json");
        ra.addFlashAttribute(MESSAGE, SAVE_SUCCESS);
        ra.addAttribute(TYPE, stat);
        return "redirect:list.do";
    }


    @ModelAttribute("bean")
    public LiveBroadcast preloadBean(@RequestParam(required = false) Integer id) {
        return id != null ? service.get(id) : null;
    }

    private void validateOptionIds(Integer[] ids, Integer siteId) {
        for (Integer id : ids) {
            Backends.validateDataInSite(service.get(id), siteId);
        }
    }

    private void validateIds(Integer[] ids, Integer siteId) {
        for (Integer id : ids) {
            Backends.validateDataInSite(service.get(id), siteId);
        }
    }

    @Autowired
    private LiveBroadcastService service;
    @Autowired
    private OperationLogService logService;
    @Autowired
    private LiveBroadcastAddressService addressService;
    @Autowired
    private UserService userService;
    @Autowired
    private InfoQueryService infoQueryService;
    @Autowired
    private NodeQueryService nodeQueryService;
    @Autowired
    private HtmlGenerator htmlGenerator;
}
